
        var elementState = {"still":1, "walking":2, "jumping":3};
        element = function (x, y, size) {
            this.maxVelocity = 11;
            this.x = x;
            this.y = y;
            this.size = size;
            this.velocity = 0;
            this.state = 0;
            this.isFacingRight = false;
            this.jumpVelocity = 0;
            this.state = new Array();
            this.frame = 0;
            this.imagesLoaded = 0;
            this.l2r = new Array();
            for (var i = 0; i < 4; i++) {
                this.l2r[i] = new Image();
                this.l2r[i].src = 'assets/l2r-000{0}.jpg'.replace("{0}", i); ;
                this.l2r[i].width = 10;
                this.l2r[i].height = 10;
                this.l2r[i].onload = function () { gameEngine.player.imagesLoaded++; }
            }
            this.r2l = new Array();
            for (var i = 0; i < 4; i++) {
                this.r2l[i] = new Image();
                this.r2l[i].src = 'assets/r2l-000{0}.jpg'.replace("{0}", i); ;
                this.r2l[i].width = 10;
                this.r2l[i].height = 10;
                this.r2l[i].onload = function () { gameEngine.player.imagesLoaded++; }
            }
            this.adjust = function (context) {
                // Fg=G(m1*m2)/d^2
                var imgdleft = context.getImageData(this.x - 1, this.y + this.size - 1, 1, 1);
                var pixleft = imgdleft.data;
                var canMoveLeft = (pixleft[3] == 0);
                var imgdright = context.getImageData(this.x + this.size + 1, this.y + this.size - 1, 1, 1);
                var pixright = imgdright.data;
                var canMoveRight = (pixright[3] == 0);
                if (this.isFacingRight) {
                    if (canMoveRight) {
                        this.x += this.velocity;
                    }
                } else {
                    if (canMoveLeft) {
                        this.x -= this.velocity;
                    }
                }
                if (this.jumpVelocity > 0) {
                    var jumpinc = (this.jumpVelocity / 3);
                    this.jumpVelocity -= Math.floor(jumpinc);
                    this.y -= jumpinc;
                    if (jumpinc < 2) {
                        this.jumpVelocity = 0;
                    }
                }
            }
            this.accelerate = function (facingRight) {
                if (facingRight == this.isFacingRight) {
                    this.velocity += 2;
                } else {
                    this.velocity -= 2;
                    if (this.velocity < 0) {
                        this.velocity = 0;
                        this.isFacingRight = facingRight;
                    }
                }
                if (this.velocity > this.maxVelocity) {
                    this.velocity = this.maxVelocity;
                }
            }
            this.decelerate = function () {
                this.velocity -= 2;
                if (this.velocity < 0) {
                    this.velocity = 0;
                    return false;
                }
                return true;
            }
            this.jump = function () {
                if (!this.state[elementState.jumping]) {
                    this.state[elementState.jumping] = true;
                    this.jumpVelocity = 125 + 5 * this.velocity;
                    this.velocity -= 2;
                }
            }

            this.draw = function (ctx) {
                this.frame++;
                this.frame = this.frame > 3 ? 0 : this.frame;
                var img = undefined;
                if (this.state[elementState.walking]) {
                    img = this.isFacingRight ? this.l2r[this.frame] : this.r2l[this.frame];
                } else if (this.state[elementState.jumping]) {
                    img = this.isFacingRight ? this.l2r[this.frame] : this.r2l[this.frame];
                } else {
                    img = this.isFacingRight ? this.l2r[1] : this.r2l[1];
                }
                if (this.imagesLoaded > 15) {
                    ctx.drawImage(img, this.x, this.y, this.size, this.size);
                } else {
                    ctx.fillStyle = "#ff0000";
                    ctx.fillRect(this.x, this.y, this.size, this.size);
                }
            }
        }
        var world = function () {
            this.maps = ["assets/levelmap1-0.png"];
            this.h = 768;
            this.w = 768;
            this.gravitate = function (body, context) {
                var mass1 = Math.PI * Math.pow((50 / 2), 2) / 1.2;
                var mass2 = Math.PI * Math.pow((body.size / 2), 2) / 1.2;
                var distance = (this.h / 2) - (body.y + body.size);
                distance = distance < 0 ? distance * -1 : distance > 25 ? 25 : distance;

                var pull = ((6.673) * (mass1 * mass2)) / Math.pow(distance, 2);
                pull = pull > 15 ? 15 : pull;
                var imgdleft = context.getImageData(body.x, body.y + body.size, 1, 1);
                var pixleft = imgdleft.data;
                var imgdright = context.getImageData(body.x + body.size, body.y + body.size, 1, 1);
                var pixright = imgdright.data;
                if (pixright[3] == pixleft[3] && pixleft[3] == 0) {
                    body.y += pull;
                } else {
                    var onGround = false;
                    while (!onGround) {
                        var pxleft = context.getImageData(body.x, body.y + body.size - 1, 1, 1).data;
                        var pxright = context.getImageData(body.x + body.size, body.y + body.size - 1, 1, 1).data;
                        if (pxright[3] == 0 || pxleft[3] == 0) {
                            onGround = true;
                            body.state[elementState.jumping] = false;
                        } else {
                            body.y--;
                            document.title = body.y;
                        }
                    }
                }
            }
        }
        var gameEngine = new function () {
            this.player = null;
            this.canvas = null;
            this.context = null;
            this.img = null;
            this.curX = 0;
            this.level = 0;
            this.world = null;
            this.keysDown = new Array();
            this.tick = function () {
                if (this.curX > this.img.width - this.canvas.width) {
                    //this.level++;
                    //setTimeout("gameEngine.start()", 1000);
                    alert("you finished!!! Well done! Come back tomorow for more.");
                    return;
                }
                this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
                this.context.drawImage(this.img, this.curX, 0, this.canvas.width, this.img.height, 0, 0, this.canvas.width, this.img.height);
                this.world.gravitate(this.player, this.context);
                this.player.adjust(this.context);
                this.player.decelerate();
                this.player.draw(this.context);
                setTimeout("gameEngine.tick()", 40);
            }
            this.handleKeys = function () {
                if (this.keysDown[38]) {
                    this.player.jump();
                }
                this.player.state[elementState.walking] = false;
                if (this.keysDown[39]) {
                    this.player.state[elementState.walking] = true;
                    this.player.accelerate(true);
                    if (this.player.x > (this.canvas.width / 100 * 60)) {
                        this.curX += this.player.velocity;
                        this.player.x -= this.player.velocity;
                    }
                }
                if (this.keysDown[37]) {
                    this.player.state[elementState.walking] = true;
                    this.player.accelerate(false);
                    if (this.player.x < (this.canvas.width / 100 * 40)) {
                        this.curX -= this.player.velocity;
                        this.player.x += this.player.velocity;
                    }
                }
                if (!(this.keysDown[39] & this.keysDown[37])) {
                    
                }
                setTimeout("gameEngine.handleKeys()", 1);
            }
            this.handleKeyUp = function (keyId) {
                this.keysDown[keyId] = false;
                return !(keyId == 38 | keyId == 39 | keyId == 40);
            }
            this.handleKeyDown = function (keyId) {
                this.keysDown[keyId] = true;
                return !(keyId == 38 | keyId == 39 | keyId == 40);
            }
            this.init = function (canvasId) {
                for (var i = 0; i < 128; i++) {
                    this.keysDown[i] = false;
                }
                this.world = new world();
                this.player = new element(50, 50, 10);
                this.player.maxVelocity = 50;
                this.canvas = document.getElementById(canvasId);
                this.context = this.canvas.getContext("2d");
                this.handleKeys();
            }
            this.start = function () {
                this.player = new element(50, 50, 50);
                this.curX = 0;
                this.img = new Image();
                this.img.src = this.world.maps[this.level];
                this.img.onload = function () {
                    gameEngine.tick();
                }
            }
        }